﻿using MQTTnet.Client;
using MQTTnet;
using MQTTnet.Extensions.ManagedClient;
using Newtonsoft.Json;
using libedi.API;
using libedi.Model.edi;

namespace CodeBackup.Code
{
    public class MqttClient
    {
        IManagedMqttClient mqttClient;

        public string Topic = Guid.NewGuid().ToString();

        public IManagedMqttClient ttClient { get { return this.mqttClient; } }
        public MqttClient() {

            // 创建一个 MQTT 客户端
            var mqttFactory = new MqttFactory();
            // mqttClient = mqttFactory.CreateMqttClient();
            WebApi webApi = new WebApi(libedi.SourceType.EDI);
            mqtt model = webApi.GetDataList<List<mqtt>>("mqtt", $"clientid='cbsappedi'").Result.FirstOrDefault();
            if (model == null)
            {
                throw new NullReferenceException("無法查詢MQTT賬戶信息!");
            }

            var options = new ManagedMqttClientOptionsBuilder()
                .WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
                .WithClientOptions(new MqttClientOptionsBuilder()
                    .WithClientId($"CODEBACKUP-{Guid.NewGuid().ToString()}") // 设置客户端 ID
                    .WithTcpServer(model.ip, model.port) // 设置MQTT服务器地址和端口
                    .WithCredentials(model.username, model.password) // 设置用户名和密码
                    .WithCleanSession() // 启用清除会话
                    .Build())
                .Build();

            mqttClient = new MqttFactory().CreateManagedMqttClient();

            mqttClient.DisconnectedAsync += e =>
            {
               // rictxt($"连接丢失，原因: {e.Reason}");

               
                return Task.CompletedTask;
            };

            // 注册事件处理器
            mqttClient.ConnectedAsync += async e =>
            {
                // 连接后订阅某个主题
                await mqttClient.SubscribeAsync(Topic);
            };


            try
            {
                // await mqttClient.ConnectAsync(options, CancellationToken.None);
                 mqttClient.StartAsync(options);
                //            // 连接后订阅某个主题
               // await mqttClient.SubscribeAsync(mqttModel.Topic);

            }
            catch (Exception ex)
            {
               MessageBox.Show(ex.Message);  
            }

        }

        public async Task BackAsync(List<string> tables)
        {
            MqModel mqttModel = new MqModel { MQTYPE = "code", Topic = Topic, data = tables };


            string json=  JsonConvert.SerializeObject(mqttModel);

            var applicationMessage = new MqttApplicationMessageBuilder()
                 .WithTopic("cbs/edi")
                 .WithPayload(json)
                 .WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce)  // QoS 2
                                                                                                     // .WithRetainFlag()
                 .Build();

             mqttClient.EnqueueAsync(applicationMessage);
        }


        public async Task Send(MqModel mqttModel)
        {


            string json = JsonConvert.SerializeObject(mqttModel);

            var applicationMessage = new MqttApplicationMessageBuilder()
                 .WithTopic("cbs/edi")
                 .WithPayload(json)
                 .WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce)  // QoS 2
                                                                                                     // .WithRetainFlag()
                 .Build();

            mqttClient.EnqueueAsync(applicationMessage);
        }


        public async Task Send(string MethedID,object data)
        {

            MqModel mqttModel = new MqModel { MethedID= MethedID, MQTYPE = "code", Topic = Topic, data = data };

            string json = JsonConvert.SerializeObject(mqttModel);

            var applicationMessage = new MqttApplicationMessageBuilder()
                 .WithTopic(CodeConfig.ServerTopic)
                 .WithPayload(json)
                 .WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce)  // QoS 2
                                                                                                     // .WithRetainFlag()
                 .Build();

           await mqttClient.EnqueueAsync(applicationMessage);
        }
    }
}
